﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using System.Linq;

namespace LnkmedDataCollect
{
    class Program
    {
        const string sqlConnectionString = "Server=.;Database=LnkmedDataCollect;User ID=sa;Password=123456;MultipleActiveResultSets=true;";
        static HttpClient client;

        static Program()
        {
            var handler = new HttpClientHandler() { UseCookies = true };
            client = new HttpClient(handler);
            client.DefaultRequestHeaders.Add("Cookie", "SESSION=ZTdjNjk0YTktZTJkMS00MTI0LWExMzMtOTYwOTRhMmFhM2Q3; edc.session.id=606d724c-69e5-472f-9189-1c9282cfaff5; JSESSIONID=684031A9D70D35D9ED21B5ADC709FA3A");
            client.DefaultRequestHeaders.Add("Accept", "application/json, text/javascript, */*; q=0.01");
            client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate, br");
            client.DefaultRequestHeaders.Add("Accept-Language", "zh-CN,zh;q=0.9");
            client.DefaultRequestHeaders.Add("Connection", "keep-alive");
            //client.DefaultRequestHeaders.Add("Content-Type", "application/json");
            client.DefaultRequestHeaders.Add("Host", "www.lnkmed.com");
            client.DefaultRequestHeaders.Add("Origin", "https://www.lnkmed.com");
            client.DefaultRequestHeaders.Add("Referer", "https://www.lnkmed.com/edc/a/sysIndex");
            client.DefaultRequestHeaders.Add("Sec-Fetch-Dest", "empty");
            client.DefaultRequestHeaders.Add("Sec-Fetch-Mode", "cors");
            client.DefaultRequestHeaders.Add("Sec-Fetch-Site", "same-origin");
            client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36");
            client.DefaultRequestHeaders.Add("X-Requested-With", "XMLHttpRequest");
            client.DefaultRequestHeaders.Add("sec-ch-ua", "\"Google Chrome\";v=\"105\", \"Not)A; Brand\";v=\"8\", \"Chromium\";v=\"105\"");
            client.DefaultRequestHeaders.Add("sec-ch-ua-mobile", " ?0");
            client.DefaultRequestHeaders.Add("sec-ch-ua-platform", "Windows");
        }

        static void Main(string[] args)
        {
            string saveBasePath = @"D:\Dev\LnkmedDataCollect\docs\dataCache\" + DateTime.Now.ToString("yyyyMMdd");
            string saveDetailPath = $"{saveBasePath}\\表单设计_详细";
            string saveValidPath = $"{saveBasePath}\\表单设计_数据校验";
            string saveDictPath = $"{saveBasePath}\\数据字典";
            if (!Directory.Exists(saveBasePath))
            {
                Directory.CreateDirectory(saveBasePath);
            }
            if (!Directory.Exists(saveDetailPath))
            {
                Directory.CreateDirectory(saveDetailPath);
            }
            if (!Directory.Exists(saveValidPath))
            {
                Directory.CreateDirectory(saveValidPath);
            }
            if (!Directory.Exists(saveDictPath))
            {
                Directory.CreateDirectory(saveDictPath);
            }

            try
            {
                CleanAllData();
                var itvString = GetItvList().Result;
                SaveItvToSql(itvString);
                File.WriteAllText($"{saveBasePath}\\访视设计.txt", itvString);

                var edcformListString = GetEdcformList().Result;
                SaveEdcformToSql(edcformListString);
                File.WriteAllText($"{saveBasePath}\\表单设计.txt", edcformListString);

                var edcformList = JsonConvert.DeserializeObject<JObject>(edcformListString);
                foreach (JObject eItem in edcformList.Value<JArray>("list"))
                {
                    var id = eItem.Value<string>("id");
                    var detailString = GetEdcformDetail(id).Result;
                    SaveEdcAttbToSql(detailString);
                    File.WriteAllText($"{saveDetailPath}\\{id}.txt", detailString);

                    var validString = GetEdcformValidlist(id).Result;
                    SaveEdcformValidToSql(validString);
                    File.WriteAllText($"{saveValidPath}\\{id}.txt", validString);
                }

                var dictListString = GetCommonDictList().Result;
                SaveCommonDictListToSql(dictListString);
                File.WriteAllText($"{saveBasePath}\\数据字典.txt", edcformListString);

                var dictList = JsonConvert.DeserializeObject<List<Dict>>(dictListString);
                foreach (var dictItem in dictList)
                {
                    var dictDetailString = GetCommonDictDetail(dictItem.type, dictItem.description).Result;
                    SaveCommonDictDetailToSql(dictDetailString);
                    File.WriteAllText($"{saveDictPath}\\{dictItem.type}_{dictItem.description}.txt", dictDetailString);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message + Environment.NewLine + e.StackTrace);
            }
            Console.WriteLine("执行完成");
            Console.ReadKey();
        }


        static async Task<string> GetItvList()
        {
            var json = "{\"pageNo\":1,\"pageSize\":100,\"edcProId\":\"0a1e6e4b820d4a838501d1291a318c2a\",\"likeCriteria\":{\"fsmc\":\"\",\"edc_subgroup_id\":\"\"},\"equalCriteria\":{\"fslb\":\"\",\"delFlag\":\"\",\"isCureRear\":\"\"}}";
            var reqData = new StringContent(json, Encoding.UTF8, "application/json");
            var resp = await client.PostAsync("https://www.lnkmed.com/edc/a/app/itv/list", reqData);
            return await resp.Content.ReadAsStringAsync();
        }
        static async Task<string> GetEdcformList()
        {
            var json = "{\"pageNo\":1,\"delFlag\":\"\",\"retype\":\"\",\"formid\":\"\",\"formname\":\"\",\"pageSize\":100}";
            var reqData = new StringContent(json, Encoding.UTF8, "application/json");
            var resp = await client.PostAsync("https://www.lnkmed.com/edc/a/app/edcform/list", reqData);
            return await resp.Content.ReadAsStringAsync();
        }
        static async Task<string> GetEdcformDetail(string id)
        {
            var json = "{\"id\":\"" + id + "\"}";
            var reqData = new StringContent(json, Encoding.UTF8, "application/json");
            var resp = await client.PostAsync("https://www.lnkmed.com/edc/a/app/edcform/detail", reqData);
            return await resp.Content.ReadAsStringAsync();
        }
        static async Task<string> GetEdcformValidlist(string id)
        {
            var reqData = new StringContent("edcformid=" + id, Encoding.UTF8, "application/x-www-form-urlencoded");
            var resp = await client.PostAsync("https://www.lnkmed.com/edc/a/edc/edcAttbValie/valielist", reqData);
            return await resp.Content.ReadAsStringAsync();
        }
        static async Task<string> GetCommonDictList() 
        {
            var reqData = new StringContent("", Encoding.UTF8, "application/json");
            var resp = await client.PostAsync("https://www.lnkmed.com/edc/a/app/common/dict/list", reqData);
            return await resp.Content.ReadAsStringAsync();
        }
        static async Task<string> GetCommonDictDetail(string type, string desc) 
        {
            var reqData = new StringContent("{\"type\":\"" + type + "\",\"description\":\"" + desc + "\"}", Encoding.UTF8, "application/json");
            var resp = await client.PostAsync("https://www.lnkmed.com/edc/a/app/common/dict/detail", reqData);
            return await resp.Content.ReadAsStringAsync();
        }


        static void CleanAllData()
        {
            var cleanSql1 = @"truncate table itv";
            var cleanSql2 = @"truncate table edcform";
            var cleanSql3 = @"truncate table edcAttb";
            var cleanSql4 = @"truncate table edcValidForminfo";
            var cleanSql5 = @"truncate table edcValidDetail";
            var cleanSql6 = @"truncate table edcValidDetailItem";
            var cleanSql7 = @"truncate table edcValidDetailSub";
            var cleanSql8 = @"truncate table dict";
            var cleanSql9 = @"truncate table dictDetail";
            using (var db = new SqlConnection(sqlConnectionString))
            {
                db.Execute(cleanSql1);
                db.Execute(cleanSql2);
                db.Execute(cleanSql3);
                db.Execute(cleanSql4);
                db.Execute(cleanSql5);
                db.Execute(cleanSql6);
                db.Execute(cleanSql7);
                db.Execute(cleanSql8);
                db.Execute(cleanSql9);
            }
        }
        static void SaveItvToSql(string data)
        {
            var sql = @"
insert into itv (formid, rijg, is_inc_itv, fsen, num, kssj_form_id, create_by, fsmc, ksjc, gsjc, id, time_from_baseline, create_date, update_by, edcSubgroupName, del_flag, kssj_dict_id, is_cure_rear, 
	kssj_attb_id, issubjfirstin, sort, update_date, fslb, edc_subgroup_id, edc_pro_id, meterage, remarks)
values (@formid, @rijg, @is_inc_itv, @fsen, @num, @kssj_form_id, @create_by, @fsmc, @ksjc, @gsjc, @id, @time_from_baseline, @create_date, @update_by, @edcSubgroupName, @del_flag, @kssj_dict_id, @is_cure_rear, 
	@kssj_attb_id, @issubjfirstin, @sort, @update_date, @fslb, @edc_subgroup_id, @edc_pro_id, @meterage, @remarks)";

            var datas = JsonConvert.DeserializeObject<RespData<Itv>>(data);

            using (var db = new SqlConnection(sqlConnectionString))
            {
                db.Execute(sql, datas.list);
            }
        }
        static void SaveEdcformToSql(string data)
        {
            var sql = @"
insert into edcform (id,isNewRecord, remarks, createDate, updateDate, delFlag, sourcePort, formid, itvid, formname, ver, edcProId, pritable, linktable, linktablerp, sort, retype, [state], formpub, pubstlye, pagename, renewid, formmodelid, isapplylogic, ds, isChkTimeRequired, edcFormList, notSet, del, startTime, endTime, enteringUser)
values (@id, @isNewRecord, @remarks, @createDate, @updateDate, @delFlag, @sourcePort, @formid, @itvid, @formname, @ver, @edcProId, @pritable, @linktable, @linktablerp, @sort, @retype, @state, @formpub, @pubstlye, @pagename, @renewid, @formmodelid, @isapplylogic, @ds, @isChkTimeRequired, @edcFormList, @notSet, @del, @startTime, @endTime, @enteringUser)";

            var datas = JsonConvert.DeserializeObject<RespData<Edcform>>(data);

            using (var db = new SqlConnection(sqlConnectionString))
            {
                db.Execute(sql, datas.list);
            }
        }
        static void SaveEdcAttbToSql(string data)
        {
            var sql = @"
insert into edcAttb (id, formId, isNewRecord, remarks, createDate, updateDate, delFlag, sourcePort, attben, attbcn, ctltype, datatype, dicttype, parentid, sort, dqcset, renewid, attbmodelid, exportattben, analysisIndex, parentSort, edcAttbList, connFormId, connAttbId)
values (@id, @formId, @isNewRecord, @remarks, @createDate, @updateDate, @delFlag, @sourcePort, @attben, @attbcn, @ctltype, @datatype, @dicttype, @parentid, @sort, @dqcset, @renewid, @attbmodelid, @exportattben, @analysisIndex, @parentSort, @edcAttbList, @connFormId, 
@connAttbId)";

            var datas = JsonConvert.DeserializeObject<Edcform>(data);

            using (var db = new SqlConnection(sqlConnectionString))
            {
                db.Execute(sql, datas.edcAttbList.ToList());
            }
        }
        static void SaveEdcformValidToSql(string data)
        {
            var formInfoSql = @"
insert into edcValidForminfo (formid, fsmc, fslb, fsen, formname, itvid, proname, id)
values (@formid, @fsmc, @fslb, @fsen, @formname, @itvid, @proname, @id)";
            var detailSql = @"
insert into edcValidDetail (minlength, attbmodelid, attbValieCopmlist, basevali, layer, valieregx, attbcn, equaltoExpression, attben, datatype, equaltoargs, equaltoExpressionList, dicttype, edcformid, clength, rtd, [maxlength], dqcset, equalto, sort, initval, exportattben, maxval, minval, ctltype, style, edcattbvalieid, edcattbid, prompt, remarks)
values (@minlength, @attbmodelid, @attbValieCopmlist, @basevali, @layer, @valieregx, @attbcn, @equaltoExpression, @attben, @datatype, @equaltoargs, @equaltoExpressionList, @dicttype, @edcformid, @clength, @rtd, @maxlength, @dqcset, @equalto, @sort, @initval, @exportattben, @maxval, @minval, @ctltype, @style, @edcattbvalieid, @edcattbid, @prompt, @remarks)";
            var detailItemSql = @"
insert into edcValidDetailItem (parentid, eoperator, dval, sattbid, doper, sval, soper, edcattbvalielistid, jsvalie, dattbid)
values (@parentid, @eoperator, @dval, @sattbid, @doper, @sval, @soper, @edcattbvalielistid, @jsvalie, @dattbid)";
            var subSql = @"
insert into edcValidDetailSub (parentid, minlength, attbmodelid, basevali, layer, valieregx, attbcn, equaltoExpression, attben, datatype, equaltoargs, dicttype, edcformid, clength, rtd, [maxlength], dqcset, equalto, sort, initval, exportattben, maxval, minval, ctltype, style, edcattbvalieid, edcattbid, prompt, remarks)
values (@parentid, @minlength, @attbmodelid, @basevali, @layer, @valieregx, @attbcn, @equaltoExpression, @attben, @datatype, @equaltoargs, @dicttype, @edcformid, @clength, @rtd, @maxlength, @dqcset, @equalto, @sort, @initval, @exportattben, @maxval, @minval, @ctltype, @style, @edcattbvalieid, @edcattbid, @prompt, @remarks)";

            var datas = JsonConvert.DeserializeObject<RespDataWithValid>(data);

            using (var db = new SqlConnection(sqlConnectionString))
            {
                db.Execute(formInfoSql, datas.data.forminfo.ToList());
                db.Execute(detailSql, datas.data.list.ToList());
                db.Execute(detailItemSql, datas.data.list.SelectMany(sm => sm.edcattbvalielist.Select(s => { s.parentid = sm.edcattbid; return s; })).ToList());
                db.Execute(subSql, datas.data.list.SelectMany(sm => sm.sublist.Select(s => { s.parentid = sm.edcattbid; return s; })).ToList());
            }
        }


        static void SaveCommonDictListToSql(string data) 
        {
            var sql = @"
insert into dict (id, [description], [type]) 
values (@id, @description, @type)";
            var datas = JsonConvert.DeserializeObject<List<Dict>>(data);
            using (var db = new SqlConnection(sqlConnectionString)) 
            {
                db.Execute(sql, datas);
            }
        }
        static void SaveCommonDictDetailToSql(string data)
        {
            var sql = @"
insert into dictDetail(id, isNewRecord, remarks, createDate, updateDate, delFlag, sourcePort, [value], [label], [type], [description], sort, parentId, edcProId)
values (@id, @isNewRecord, @remarks, @createDate, @updateDate, @delFlag, @sourcePort, @value, @label, @type, @description, @sort, @parentId, @edcProId)";
            var datas = JsonConvert.DeserializeObject<List<DictDetail>>(data);
            using (var db = new SqlConnection(sqlConnectionString))
            {
                db.Execute(sql, datas);
            }
        }
    }
    public class RespData<T>
    {
        public int pageNo { get; set; }
        public int pageSize { get; set; }
        public int count { get; set; }
        public List<T> list { get; set; }
    }

    public class Itv
    {
        public string formid { get; set; }
        public string rijg { get; set; }
        public string is_inc_itv { get; set; }
        public string fsen { get; set; }
        public string num { get; set; }
        public string kssj_form_id { get; set; }
        public string create_by { get; set; }
        public string fsmc { get; set; }
        public string ksjc { get; set; }
        public string gsjc { get; set; }
        public string id { get; set; }
        public string time_from_baseline { get; set; }
        public string create_date { get; set; }
        public string update_by { get; set; }
        public string edcSubgroupName { get; set; }
        public string del_flag { get; set; }
        public string kssj_dict_id { get; set; }
        public string is_cure_rear { get; set; }
        public string kssj_attb_id { get; set; }
        public string issubjfirstin { get; set; }
        public string sort { get; set; }
        public string update_date { get; set; }
        public string fslb { get; set; }
        public string edc_subgroup_id { get; set; }
        public string edc_pro_id { get; set; }
        public string meterage { get; set; }
        public string remarks { get; set; }
    }

    public class Edcform
    {
        public string id { get; set; }
        public string isNewRecord { get; set; }
        public string remarks { get; set; }
        public string createDate { get; set; }
        public string updateDate { get; set; }
        public string delFlag { get; set; }
        public string sourcePort { get; set; }
        public string formid { get; set; }
        public string itvid { get; set; }
        public string formname { get; set; }
        public string ver { get; set; }
        public string edcProId { get; set; }
        public string pritable { get; set; }
        public string linktable { get; set; }
        public string linktablerp { get; set; }
        public string sort { get; set; }
        public string retype { get; set; }
        public string state { get; set; }
        public string formpub { get; set; }
        public string pubstlye { get; set; }
        public string pagename { get; set; }
        public string renewid { get; set; }
        public string formmodelid { get; set; }
        public string isapplylogic { get; set; }
        public string ds { get; set; }
        public string isChkTimeRequired { get; set; }
        public string edcFormList { get; set; }
        public string notSet { get; set; }
        public string del { get; set; }
        public string startTime { get; set; }
        public string endTime { get; set; }
        public string enteringUser { get; set; }

        //public string edcAttbList           { get; set; }
        //public string edcLabListList        { get; set; }
        //public string labModelListList      { get; set; }
        
        public List<EdcAttb> edcAttbList { get; set; } = new List<EdcAttb>();
    }

    public class EdcAttb
    {
        public string id { get; set; }
        public string formId => edcForm.id;
        public string isNewRecord { get; set; }
        public string remarks { get; set; }
        public string createDate { get; set; }
        public string updateDate { get; set; }
        public string delFlag { get; set; }
        public string sourcePort { get; set; }
        public string attben { get; set; }
        public string attbcn { get; set; }
        public string ctltype { get; set; }
        public string datatype { get; set; }
        public string dicttype { get; set; }
        public string parentid { get; set; }
        public string layer { get; set; }
        public string sort { get; set; }
        public string dqcset { get; set; }
        public string renewid { get; set; }
        public string attbmodelid { get; set; }
        public string exportattben { get; set; }
        public string analysisIndex { get; set; }
        public string parentSort { get; set; }
        public string edcAttbList { get; set; }
        public string connFormId { get; set; }
        public string connAttbId { get; set; }

        public Edcform edcForm { get; set; } = new Edcform();
    }



    public class RespDataWithValid
    {
        public string status { get; set; }
        public string message { get; set; }
        public ValidData data { get; set; }
    }
    public class ValidData 
    {
        public bool isSavedValie { get; set; }
        public List<ValidFromInfo> forminfo { get; set; }
        public List<ValidDetail> list { get; set; }
    }
    public class ValidFromInfo
    {
        public string formid { get; set; }
        public string fsmc { get; set; }
        public string fslb { get; set; }
        public string fsen { get; set; }
        public string formname { get; set; }
        public string itvid { get; set; }
        public string proname { get; set; }
        public string id { get; set; }
    }
    public class ValidDetail 
    {
        public string minlength { get; set; }
        public string attbmodelid { get; set; }
        public JArray attbValieCopmlist { get; set; }
        //public string attbValieCopmlistTxt => attbValieCopmlist.ToString();

        /// <summary>
        /// leastone 应用于子表格，表示至少一条数据
        /// leastdate1 时间至少输入至 年,  年 月 日 时 分
        /// required 必填
        /// digits="true" 整数，没有小数点后
        /// systime 禁止录入超前时间
        /// </summary>
        public string basevali { get; set; }
        public string layer { get; set; }
        public string valieregx { get; set; }
        public string attbcn { get; set; }
        public string equaltoExpression { get; set; }
        public string attben { get; set; }
        public string datatype { get; set; }
        public string equaltoargs { get; set; }
        public JArray equaltoExpressionList { get; set; }
        //public string equaltoExpressionListTxt => equaltoExpressionList.ToString();

        public string dicttype { get; set; }
        public string edcformid { get; set; }
        public string clength { get; set; }
        public List<ValidDetailItem> edcattbvalielist { get; set; } = new List<ValidDetailItem>();
        public string rtd { get; set; }
        public string maxlength { get; set; }
        public string dqcset { get; set; }
        public string equalto { get; set; }
        public string sort { get; set; }
        public string initval { get; set; }
        public string exportattben { get; set; }
        public string maxval { get; set; }
        public string minval { get; set; }
        public List<ValidDetailSub> sublist { get; set; } = new List<ValidDetailSub>();
        public string ctltype { get; set; }
        public string style { get; set; }
        public string edcattbvalieid { get; set; }
        public string edcattbid { get; set; }
        public string prompt { get; set; }
        public string remarks { get; set; }

    }
    public class ValidDetailItem
    {
        public string parentid { get; set; }

        public string eoperator { get; set; }

        public string sattbid { get; set; }

        /// <summary>
        /// b 值 隐藏显示
        /// </summary>
        public string dval { get; set; }

        /// <summary>
        /// b的判断条件
        /// </summary>
        public string doper { get; set; }

        /// <summary>
        /// a值
        /// </summary>
        public string sval { get; set; }

        /// <summary>
        /// a的判断条件
        /// </summary>
        public string soper { get; set; }
        public string edcattbvalielistid { get; set; }
        public string jsvalie { get; set; }

        /// <summary>
        /// 关联属性id
        /// </summary>
        public string dattbid { get; set; }
    }
    public class ValidDetailSub 
    {
        public string parentid { get; set; }

        public string minlength { get; set; }
        public string attbmodelid { get; set; }
        public string basevali { get; set; }
        public string layer { get; set; }
        public string valieregx { get; set; }
        public string attbcn { get; set; }
        public string equaltoExpression { get; set; }
        public string attben { get; set; }
        public string datatype { get; set; }
        public string equaltoargs { get; set; }
        public string dicttype { get; set; }
        public string edcformid { get; set; }
        public string clength { get; set; }
        public string rtd { get; set; }
        public string maxlength { get; set; }
        public string dqcset { get; set; }
        public string equalto { get; set; }
        public string sort { get; set; }
        public string initval { get; set; }
        public string exportattben { get; set; }
        public string maxval { get; set; }
        public string minval { get; set; }
        public string ctltype { get; set; }
        public string style { get; set; }
        public string edcattbvalieid { get; set; }
        public string edcattbid { get; set; }
        public string prompt { get; set; }
        public string remarks { get; set; }
    }

    public class Dict 
    {
        public string id { get; set; }
        public string description { get; set; }
        public string type { get; set; }
    }
    public class DictDetail
    {
        public string id { get; set; }
        public string isNewRecord { get; set; }
        public string remarks { get; set; }
        public string createDate { get; set; }
        public string updateDate { get; set; }
        public string delFlag { get; set; }
        public string sourcePort { get; set; }
        public string value { get; set; }
        public string label { get; set; }
        public string type { get; set; }
        public string description { get; set; }
        public string sort { get; set; }
        public string parentId { get; set; }
        public string edcProId { get; set; }
    }


}
